using System;
using System.Collections.Generic;
using System.Threading;
using CatLib.Container;
using Cysharp.Threading.Tasks;
using GameFramework.Core;
using GameFramework.Reference;
using GameFramework.Request;

namespace GameFramework.Rpc
{
    internal sealed partial class RpcServiceImpl : IInitialize, IDisposable, IRpcService
    {
        [Inject]
        public IReferenceService ReferenceService { get; set; }
        
        private uint m_RpcIdIncrease;
        private readonly Dictionary<uint, RpcWaiter> m_Waiters = new Dictionary<uint, RpcWaiter>();

        public void Initialize()
        {
        }

        public void Dispose()
        {
        }

        public IRpcWaiter Allocate()
        {
            var waiter = ReferenceService.GetReference<RpcWaiter>();
            waiter.OnDisposeAction = OnDisposeWaiter;
            waiter.RpcId = ++m_RpcIdIncrease;
            return waiter;
        }

        private void OnDisposeWaiter(RpcWaiter waiter)
        {
            m_Waiters.Remove(waiter.RpcId);
            waiter.Recycle();
        }

        public void SetResponse(uint rpcId, IResponse response)
        {
            if (!m_Waiters.TryGetValue(rpcId, out var waiter))
            {
                response.Recycle();
                return;
            }
            
            waiter.SetResponse(response);
        }
    }
}